home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / src / spr12.lha / remove2.c < prev    next >
C/C++ Source or Header  |  1995-10-31  |  4KB  |  235 lines

  1.  
  2. #include <exec/types.h>
  3. #include <exec/execbase.h>
  4. #include <exec/tasks.h>
  5. #include <clib/exec_protos.h>
  6. #include <pragmas/exec_sysbase_pragmas.h>
  7.  
  8. GLOBAL UBYTE patchStart;
  9. GLOBAL UBYTE patchEnd;
  10. GLOBAL UBYTE codeStart;
  11. GLOBAL UBYTE codeEnd;
  12.  
  13. GLOBAL ULONG NCount_Offset;
  14. GLOBAL ULONG UCount_Offset;
  15. GLOBAL ULONG SigBit_Offset;
  16. GLOBAL ULONG Task_Offset;
  17. GLOBAL ULONG RtsNop_Offset;
  18.  
  19. GLOBAL struct ExecBase *SysBase;
  20. GLOBAL struct Library *LibBase;
  21. GLOBAL ULONG LVO;
  22. GLOBAL ULONG (*OldRoutine)();
  23.  
  24. /*
  25. ||
  26. || Remove the patch and free it's storage.
  27. ||
  28. || "patch" points to the beginning of the patches storage.
  29. ||
  30. */
  31. LONG
  32. remove( UBYTE *patch )
  33. {
  34.    UBYTE *pc;
  35.    ULONG *ncount;
  36.    ULONG *ucount;
  37.    ULONG *sigbit;
  38.    struct Task **task;
  39.    UWORD *rtsnop;
  40.    UBYTE *vecBeg;
  41.    UBYTE *vecEnd;
  42.    struct Node *node;
  43.    ULONG count;
  44.  
  45.    /*
  46.    ||
  47.    || Protect.
  48.    ||
  49.    */
  50.    Forbid();
  51.  
  52.    /*
  53.    ||
  54.    || Replace our vector with the original.
  55.    ||
  56.    */
  57.    SetFunction( LibBase, LVO, OldRoutine );
  58.  
  59.    /*
  60.    ||
  61.    || Calculate variable addresses.
  62.    ||
  63.    */
  64.    ncount = ( ULONG * )        ( patch + NCount_Offset );
  65.    ucount = ( ULONG * )        ( patch + UCount_Offset );
  66.    sigbit = ( ULONG * )        ( patch + SigBit_Offset );
  67.    task   = ( struct Task ** ) ( patch + Task_Offset   );
  68.    rtsnop = ( UWORD *)         ( patch + RtsNop_Offset );
  69.  
  70.    /*
  71.    ||
  72.    || Calculate library vector start and end address.
  73.    ||
  74.    */
  75.    vecBeg = ( (UBYTE *)LibBase ) + LVO;
  76.    vecEnd = vecBeg + LIB_VECTSIZE;
  77.  
  78.    /*
  79.    ||
  80.    || Setup signaling info.
  81.    ||
  82.    */
  83.    *sigbit = AllocSignal( -1 );
  84.    *task = FindTask( NULL );
  85.  
  86.    /*
  87.    ||
  88.    || Initialize "ucount" to current nesting count.
  89.    ||
  90.    */
  91.    *ucount = *ncount;
  92.  
  93.    /*
  94.    ||
  95.    || Count the number of tasks executing within our code.
  96.    ||
  97.    */
  98.    for ( node = SysBase->TaskReady.lh_Head ; node->ln_Succ ; node = node->ln_Succ )
  99.    {
  100.       pc = (UBYTE *) *( (ULONG *) ( (struct Task *) node )->tc_SPReg );
  101.       if ( ( pc >= vecBeg && pc < vecEnd )  ||
  102.            ( pc >= &codeStart && pc < &codeEnd ) )
  103.       {
  104.          (*ucount)++;
  105.       }
  106.    }
  107.  
  108.    /*
  109.    ||
  110.    || Count the number of tasks executing within our code.
  111.    ||
  112.    */
  113.    for ( node = SysBase->TaskWait.lh_Head ; node->ln_Succ ; node = node->ln_Succ )
  114.    {
  115.       pc = (UBYTE *) *( (ULONG *) ( (struct Task *) node )->tc_SPReg );
  116.       if ( ( pc >= vecBeg && pc < vecEnd )  ||
  117.            ( pc >= &codeStart && pc < &codeEnd ) )
  118.       {
  119.          (*ucount)++;
  120.       }
  121.    }
  122.  
  123.    /*
  124.    ||
  125.    || Cache use count.
  126.    ||
  127.    */
  128.    count = *ucount;
  129.  
  130.    /*
  131.    ||
  132.    || Now change the RTS at the end of our routine to a NOP to activate
  133.    || removal code.
  134.    ||
  135.    */
  136.    *rtsnop = 0x4e71;
  137.  
  138.    /*
  139.    ||
  140.    || Flush the cache.
  141.    ||
  142.    */
  143.    CacheClearU();
  144.  
  145.    /*
  146.    ||
  147.    || Enable task switching.
  148.    ||
  149.    */
  150.    Permit();
  151.  
  152.    /*
  153.    ||
  154.    || Wait for the patch to signal us, only if the use count is not zero.
  155.    ||
  156.    */
  157.    if ( count != 0 )
  158.    {
  159.       Wait( *sigbit );
  160.  
  161.       /*
  162.       ||
  163.       || Wait until the final patch exits.
  164.       ||
  165.       */
  166.       do
  167.       {
  168.          /*
  169.          ||
  170.          || Wait a little bit.
  171.          ||
  172.          */
  173.          Delay(50);
  174.  
  175.          /*
  176.          ||
  177.          || Initialize variable.
  178.          ||
  179.          */
  180.          count = 0;
  181.  
  182.          /*
  183.          ||
  184.          || Count the number of tasks executing within our code.
  185.          ||
  186.          */
  187.          for ( node = SysBase->TaskReady.lh_Head ; node->ln_Succ ; node = node->ln_Succ )
  188.          {
  189.             pc = (UBYTE *) *( (ULONG *) ( (struct Task *) node )->tc_SPReg );
  190.             if ( ( pc >= vecBeg && pc < vecEnd )  ||
  191.                  ( pc >= &codeStart && pc < &codeEnd ) )
  192.             {
  193.                count++;
  194.             }
  195.          }
  196.    
  197.          /*
  198.          ||
  199.          || Count the number of tasks executing within our code.
  200.          ||
  201.          */
  202.          for ( node = SysBase->TaskWait.lh_Head ; node->ln_Succ ; node = node->ln_Succ )
  203.          {
  204.             pc = (UBYTE *) *( (ULONG *) ( (struct Task *) node )->tc_SPReg );
  205.             if ( ( pc >= vecBeg && pc < vecEnd )  ||
  206.                  ( pc >= &codeStart && pc < &codeEnd ) )
  207.             {
  208.                count++;
  209.             } 
  210.          }
  211.       } while ( count != 0 );
  212.    }
  213.  
  214.    /*
  215.    ||
  216.    || Free the signal.
  217.    ||
  218.    */
  219.    FreeSignal( *sigbit );
  220.  
  221.    /*
  222.    ||
  223.    || Now free the patch storage.
  224.    ||
  225.    */
  226.    FreeVec( patch );
  227.  
  228.    /*
  229.    ||
  230.    || We're done.
  231.    ||
  232.    */
  233.    return 0;
  234. }
  235.